home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Gold Collection / Software Vault - The Gold Collection (American Databankers) (1993).ISO / cdr49 / 109_01.zip / SEARCH.ASM < prev    next >
Assembly Source File  |  1993-06-26  |  12KB  |  550 lines

  1. ;     SEARCH.ASM
  2. ;
  3. ;    Version 1.2    30-June-80
  4. ;
  5. ;      this program searches RAM or a file for the specified
  6. ;    data and reports the addresses of any occurences. in the
  7. ;    case of a file, the entire file is read into RAM in order
  8. ;    to search as quickly as possible (a 16K file is searched
  9. ;    in less than 10 seconds) - the size of the file that may be
  10. ;    searched is limited therefore by memory size. an attempt
  11. ;    to read a file that is too large will result in an error
  12. ;    message - the file however will be compared as far as
  13. ;    possible.
  14. ;    
  15. ;    protocol: A>SEARCH RA STRING                  (RAM  ASCII data)
  16. ;            SEARCH RH XX XX XX                (RAM  HEX   data)
  17. ;            SEARCH FA STRING [FILENAME.EXT]   (file ASCII data)
  18. ;            SEARCH FH XX XX XX [FILENAME.EXT] (file HEX   data)
  19. ;
  20. ;    note:      since the CP/M command line is converted
  21. ;          to UPPER CASE, the HEX data format must be
  22. ;          used to search for lower case characters.
  23. ;
  24. ;          addresses are given in HEX and offset octal format for
  25. ;          RAM searches, and in sector-byte format for file
  26. ;          searches.
  27. ;
  28. BASE    EQU    4200H        ; HEATH base
  29. BDOS    EQU    BASE+5        ; entry point to DOS
  30. MEMSIZ    EQU    BASE+2        ; last page of system memory
  31. TBUFF    EQU    BASE+80H    ; I/O buffer
  32. TPA    EQU    BASE+100H    ; Transient Program Area
  33. WRCON    EQU    2        ; write console character
  34. PRINTF    EQU    9        ; print routine
  35. OPENF    EQU    15        ; open file
  36. READF    EQU    20        ; read next record
  37. SETDMA    EQU    26        ; set DMA
  38. BELL    EQU    7        ; terminal bell
  39. LF    EQU    10        ; line feed
  40. CR    EQU    13        ; carriage return
  41. ESC    EQU    27        ; escape
  42. SECTOR    EQU    128        ; sector size
  43. BDOSERR    EQU    255        ; BDOS error code
  44. SPACE    EQU    ' '        ; space
  45. EOL    EQU    '$'        ; string terminator
  46. CHL    EQU    1894H        ; ROM complement HL routine
  47. COMP    EQU    1830H        ; ROM compare routine
  48. DU66    EQU    1846H        ; ROM divide routine
  49. CDEHL    EQU    188EH        ; ROM compare DEHL routine
  50. MOVE    EQU    18AAH        ; ROM move routine
  51. MU66    EQU    18DFH        ; ROM multiply routine
  52. RSTALL    EQU    1927H        ; ROM restore all routine
  53. SAVALL    EQU    192CH        ; ROM save all routine
  54. UDD    EQU    196FH        ; ROM unpack routine
  55. ;
  56.     ORG    TPA
  57. START:    
  58.     LDA    MEMSIZ        ; get high memory page
  59.     STA    LAST+1        ; save
  60.     LXI    H,TBUFF+1       ; point to first space
  61.     MOV    A,M        ; get char
  62.     CPI    SPACE        ; space?
  63.     JNZ    SYNERR        ; no: error
  64.     LXI    H,TBUFF+4    ; point to second space
  65.     MOV    A,M        ; get char
  66.     CPI    SPACE        ; space?
  67.     JNZ    SYNERR        ; no: error
  68.     DCX    H        ; point to mode byte 1
  69.     DCX    H        ;
  70.     MOV    A,M        ; get mode
  71.     CPI    'F'        ; file?
  72.     JZ    GOTFILE        ; yes: bypass
  73.     CPI    'R'        ; RAM?
  74.     JNZ    MODERR        ; error: process
  75. STARTF:
  76.     INX    H           ; point to mode byte 2
  77.     MOV    A,M        ; get mode
  78.     CPI    'A'        ; ASCII?
  79.     JZ    GOTASCII    ; yes: bypass
  80.     CPI    'H'        ; HEX?
  81.     JZ    GOTHEX        ; yes: bypass
  82. MODERR:
  83.     LXI    D,MODMSG    ; print error message
  84.     JMP    PRTERR        ; bypass
  85. SYNERR:
  86.     LXI    D,SYNMSG    ; msg pntr
  87. PRTERR:
  88.     CALL    PERR        ; print it
  89.     RET            ; to CP/M
  90. ;
  91. GOTHEX:
  92.     LDA    TBUFF        ; get command line count
  93.     SUI    3        ; adjust
  94.     MVI    B,0        ; divide by 3
  95.     MOV    C,A        ;
  96.     LXI    D,3        ;
  97.     CALL    DU66        ;
  98.     MOV    A,L        ; get result
  99.     STA    TBUFF        ; save as HEX data count
  100.     MOV    C,A        ; convert ASCII data
  101.     CALL    CONVERT        ;   to binary data
  102.     LDA    TBUFF        ; restore count again
  103.     JMP    HEXSTART    ; bypass
  104. GOTASCII:
  105.     LXI    H,TBUFF        ; get command length
  106.     MOV    A,M        ;
  107.     SUI    4        ; adjust
  108. HEXSTART:
  109.     MOV    C,A        ; set C to data count
  110.     LXI    D,TBUFF+5    ; set DE to data    
  111.     LHLD    FIRST        ; set HL to start of memory
  112. LOOP:    PUSH    B        ; save
  113.     PUSH    D        ;
  114.     PUSH    H        ;
  115.     CALL    COMP        ; compare data with memory
  116.     POP    H        ; restore
  117.     POP    D        ;
  118.     POP    B        ;
  119.     JZ    FOUNDIT        ; found?
  120.     INX    H        ; no: bump memory pntr
  121.     CALL    CHECKEND    ; finished?
  122.     JNZ    LOOP        ; no: continue
  123.     LDA    FLAG        ; was anything found?
  124.     CPI    0        ; 
  125.     RNZ            ; yes: return to CP/M
  126.     LXI    D,NFMSG        ; no: print 'not found'
  127.     CALL    PSTR        ;
  128.     RET            ; to CP/M
  129. ;
  130. GOTFILE:
  131.     LXI    H,TYPE
  132.     INR    M    
  133.     LXI    H,TBUFF+5    ; pntr to first byte of cmd
  134.     MVI    C,2        ; reset cntr
  135. CNTCHAR:
  136.     INR    C        ; cntr + 1
  137.     MOV    A,M        ; get char
  138.     INX    H        ; bump pntr
  139.     CPI    '['        
  140.     INX    D        ;
  141.     DCR    C        ; done?
  142.     JNZ    GETEXT1        ; no: continue
  143. DONE        ; get cntr
  144.     STA    TBUFF        ; save cntr
  145.     CALL    SAVTBUFF    ; save tbuff
  146.     SHLD    FNPNTR        ; save filename pntr
  147. ;
  148.     LXI    D,FILEFCB    ; FCB pntr
  149.     INX    H        ; bump pntr to possible ':'
  150.     MOV    A,M        ; get byte
  151.     CPI    ':'        ; drive specified?
  152.     JNZ    NODRV        ; no: bypass
  153.     DCX    H        ; get drive
  154.     MOV    A,M
  155.     SUI    'A'-1        ; subtract offset
  156.     STA    FILEFCB        ; save
  157.     INX    H        ; pntr to first letter
  158.     INX    H        ;
  159.     SHLD    FNPNTR        ; save
  160.     JMP    GET1        ; bypass
  161. NODRV:    
  162.     DCX    H        ; pntr to first letter
  163. GET1:    
  164.     LXI    D,FILEFCB+1     ; pntr to FILEFCB+1
  165.     MVI    C,8        ; cntr
  166. GETBYT:
  167.     MOV    A,M        ; get byte
  168.     CPI    '.'        ; beginning of .EXT?
  169.     JNZ    GET2        ; no: bypass
  170.     INX    H        ; bump pntr
  171.     JMP    GETEXT        ; bypass
  172. GET2:
  173.     STAX    D        ; save    
  174.     INX    H        ; bump pntrs
  175.     INX    D        ;
  176.     DCR    C        ; done?
  177.     JNZ    GETBYT        ; no: continue
  178.     MOV    A,M        ; get byte
  179.     CPI    '.'        ; extent specified?
  180.     JNZ    DONEGET        ; no: bypass
  181. GETEXT:
  182.     MVI    C,3        ; move ext
  183.     LXI    D,FILEFCB+9    ; set pntr
  184. GETEXT1:
  185.     MOV    A,M        ;
  186.     STAX    D        ;
  187.     INX    H        ; bump pntrs
  188.     INX    D        ;
  189.     DCR    C        ; done?
  190.     JNZ    GETEXT1        ; no: continue
  191. DONEGET:
  192.     CALL    READFILE    ; get file
  193.     CALL    RSTTBUFF    ;
  194.     LXI    H,TBUFF+2    ; setup
  195.     JMP    STARTF        ;
  196. SAVTBUFF:
  197.     CALL    SAVALL
  198.     LXI    B,50        ;
  199.     LXI    D,TBUFF
  200.     LXI    H,TEMPBUF
  201.     CALL    MOVE
  202.     JMP    RSTALL
  203. RSTTBUFF:
  204.     CALL    SAVALL
  205.     LXI    B,50
  206.     LXI    D,TEMPBUF
  207.     LXI    H,TBUFF
  208.     CALL    MOVE
  209.     JMP    RSTALL
  210. ;
  211. FOUNDIT:
  212.     MVI    A,1        ; set flag
  213.     STA    FLAG        ;
  214.     LDA    TYPE
  215.     ORA    A
  216.     JZ    FOUND1
  217. ;
  218.     PUSH    B
  219.     PUSH    D
  220.     PUSH    H
  221.     LHLD    FIRST
  222.     CALL    CHL
  223.     MOV    D,H
  224.     MOV    E,L
  225.     POP    H
  226.     PUSH    H
  227.     DAD    D
  228.     MOV    B,H    
  229.     MOV    C,L
  230.     LXI    D,SECTOR
  231.     CALL    DU66
  232.     PUSH    D
  233.     INX    H
  234.     MOV    B,H
  235.     MOV    C,L
  236.     MVI    A,3
  237.     LXI    H,FFMSG2
  238.     CALL    UDD
  239.     POP    D
  240.     INX    D
  241.     MOV    B,D
  242.     MOV    C,E
  243.     MVI    A,3
  244.     LXI    H,FFMSG3
  245.     CALL    UDD
  246.     LXI    D,FFMSG1
  247.     CALL    PSTR
  248.     POP    H
  249.     POP    D
  250.     POP    B
  251.        JMP    FOUND2
  252. FOUND1:
  253.     PUSH    D        ; save
  254.     LXI    D,FMSG        ; print 'found'
  255.     CALL    PSTR        ;
  256.     POP    D        ; restore
  257.     CALL    PADDR        ; print addr (hex and offset octal)
  258. FOUND2:
  259.     CALL    CHECKEND    ; finished?
  260.     RZ            ; yes: return to CP/M
  261.     INX    H        ; no: bump memory pointer
  262.     JMP    LOOP        ; continue
  263. ;
  264. ;    compare present address with high memory limit
  265. ;
  266. CHECKEND:
  267.     PUSH    D        ; save
  268.     PUSH    H        ;
  269.     XCHG            ; DE = present addr
  270.     LHLD    LAST        ; HL = high memory limit
  271.     CALL    CDEHL        ; done?
  272.     POP    H        ; restore
  273.     POP    D        ;
  274.     RET            ; return
  275. ;
  276. ;    print address in hex and split octal
  277. ;
  278. PADDR:
  279.     PUSH    B        ; save
  280.     PUSH    D        ;
  281.     PUSH    H        ;
  282.     MOV    A,H        ; print high HEX byte
  283.     CALL    PHEX        ;
  284.     MOV    A,L        ; print low HEX byte
  285.     CALL    PHEX        ;
  286.     MVI    A,' '        ; print space
  287.     CALL    PCHAR        ;
  288.     MVI    A,'('        ; print '('
  289.     CALL    PCHAR        ;
  290.     POP    H        ; restore address
  291.     PUSH    H        ; save again
  292.     MOV    A,H        ; print high OCTAL byte
  293.     CALL    POCT        ;
  294.     MVI    A,'.'        ; print '.'
  295.     CALL    PCHAR        ;
  296.     POP    H        ; restore address
  297.     PUSH    H        ; save again
  298.     MOV    A,L        ; print low OCTAL byte
  299.     CALL    POCT        ;
  300.     MVI    A,')'        ; print ')'
  301.     CALL    PCHAR        ;
  302.     MVI    A,CR        ; print CRLF
  303.     CALL    PCHAR        ;
  304.     MVI    A,LF        ;
  305.     CALL    PCHAR        ;
  306.     POP    H        ; restore
  307.     POP    D        ;
  308.     POP    B        ;    
  309.     RET            ; return
  310. ;
  311. ;    print hex byte in register A
  312. ;
  313. PHEX:
  314.     PUSH    PSW        ; save
  315.     RRC            ; shift high 4 bits
  316.     RRC            ;
  317.     RRC            ;
  318.     RRC            ;
  319.     CALL    PNIB        ; print it
  320.     POP    PSW        ; restore
  321.     CALL    PNIB        ; print it
  322.     RET            ; return
  323. ;
  324. PNIB:    
  325.     ANI    0FH        ; mask out high 4 bits
  326.     CPI    10        ; alphabetic?
  327.     JNC    P10        ; yes: bypass
  328.     ADI    '0'        ; add ASCII offset
  329.     JMP    PRN        ; bypass
  330. P10    ADI    'A'-10        ; add ASCII & letter offset    
  331. PRN    CALL    PCHAR        ; print it
  332.     RET            ; return
  333. ;
  334. ;    print character in register A
  335. ;
  336. PCHAR:
  337.     PUSH    B        ; save
  338.     PUSH    D        ;
  339.     PUSH    H        ;
  340.     MVI    C,WRCON        ; print CON: char function
  341.     MOV    E,A        ; set up -> E
  342.     CALL    BDOS        ; do it
  343.     POP    H        ; restore
  344.     POP    D        ;
  345.     POP    B        ;
  346.     RET            ; return
  347. ;
  348. ;     print EOL terminated string pointed to by DE
  349. ;
  350. PSTR:    
  351.     PUSH    B        ; save    
  352.     PUSH    D        ;
  353.     PUSH    H        ;
  354.     MVI    C,PRINTF    ; print CON: string function
  355.     CALL    BDOS        ; do it
  356.     POP    H        ; save
  357.     POP    D        ;
  358.     POP    B        ;
  359.     RET            ; return
  360. ;
  361. ;    print octal byte in register A
  362. ;
  363. POCT    PUSH    PSW        ; save
  364.     RRC            ; shift left 2 bits
  365.     RRC            ;
  366.     RRC            ;
  367.     RRC            ;
  368.     RRC            ;
  369.     RRC            ;
  370.     ANI    03H        ; mask out high 6 bits
  371.     ADI    '0'        ; add ASCII offset
  372.     CALL    PCHAR        ; print it
  373.     POP    PSW        ; restore
  374.     PUSH    PSW        ; save again
  375.     RRC            ; shift middle 3 bits
  376.     RRC            ;
  377.     RRC            ;
  378.      ANI    07H        ; mask out high 5 bits
  379.     ADI    '0'        ; add ASCII offset
  380.     CALL    PCHAR        ; print it
  381.     POP    PSW        ; restore
  382.     ANI    07H        ; mask out high 5 bits
  383.     ADI    '0'        ; add ASCII offset
  384.     CALL    PCHAR        ; print it
  385.     RET            ; return
  386. ;
  387. ;     convert HEX ASCII data to binary and save at TBUFF+4
  388. ;
  389. CONVERT:
  390.     LHLD    APNTR        ; get ASCII pntr
  391.     MOV    A,M        ; get ASCII char
  392.     CPI    'A'          ; hex letter?
  393.     JC     NOTLET1        ; no:bypass
  394.     SUI    'A'-10        ; yes: subtract ASCII & letter offset
  395.     JMP    SHIFT1        ; bypass
  396. NOTLET1:
  397.     SUI    '0'        ; subtract ASCII offset
  398. SHIFT1:
  399.     RLC            ; shift to high bit positions
  400.     RLC            ;
  401.     RLC            ;
  402.     RLC            ;
  403.     MOV    B,A        ; save
  404.     INX    H        ; bump ASCII pntr
  405.     MOV    A,M        ; get ASCII char
  406.     CPI    'A'          ; hex letter?
  407.     JC     NOTLET2        ; no: bypass
  408.     SUI    'A'-10        ; yes: subtract ASCII & letter offset
  409.     JMP    MERGE         ; bypass
  410. NOTLET2:
  411.     SUI    '0'        ; subtract ASCII offset
  412. MERGE:
  413.     ORA    B        ; combine high and low order bits
  414.     LHLD    BPNTR        ; get binary pntr
  415.      MOV    M,A        ; save binary data
  416.     INX    H        ; bump binary pntr
  417.     SHLD    BPNTR        ; save
  418.     LHLD    APNTR        ; restore ASCII pntr
  419.     INX    H        ; bump it 3 times (past space)
  420.     INX    H        ;
  421.     INX    H        ;
  422.     SHLD    APNTR        ; save
  423.     DCR    C        ; finished?
  424.     JNZ    CONVERT        ; no: continue
  425.     RET            ; return
  426. ;
  427. ;    open file at FILEFCB
  428. ;
  429. OPENFILE:
  430.     MVI    C,OPENF        ; open file
  431.     LXI    D,FILEFCB    ;
  432.     CALL    BDOS        ;
  433.     CPI    BDOSERR        ; error?
  434.     RET
  435. ;
  436. ;    read file into RAM beginning at BUFFER
  437. ;
  438. READFILE:    
  439.     CALL    OPENFILE    ; open: error?
  440.     JNZ    READ1        ; no: bypass
  441.     POP    PSW        ; discard RET addr
  442.     LXI    D,OPENERR    ; print error
  443.     JMP    PRTERR
  444. READ1:
  445.     LXI    D,BUFFER    ; set DMA addr to BUFFER
  446.     CALL    SETADDR        ;
  447.     MVI    C,READF        ; read file until EOF
  448.          LXI    D,FILEFCB    ;
  449. RLOOP:
  450.     PUSH    B        ; save
  451.     PUSH    D        ;
  452.     PUSH    H        ;
  453.     CALL    BDOS        ;
  454.     LXI    H,TOTAL        ; increment total read
  455.     INR    M        ;
  456.     STA    TEMP
  457.     POP    H        ; restore
  458.     POP    D        ;
  459.     POP    B        ;
  460.     CALL    INRADDR        ; 
  461.     JC     TOOBIG
  462.     LDA    TEMP
  463.     ORA    A
  464.     JZ     RLOOP        ; no: continue
  465. ;
  466. TOOBIG:
  467.     LXI    H,TOTAL        ; read past end: adjust
  468.     DCR    M
  469.     LXI    D,TBUFF        ; reset DMA
  470.     CALL    SETADDR        ;
  471.     LXI    H,BUFFER    ; set pntr to first addr
  472.     SHLD    FIRST        ;
  473.     PUSH    H
  474.     LXI     B,SECTOR    ; multiply total * 128
  475.     LHLD    TOTAL        ;
  476.     XCHG            ;
  477.     CALL    MU66        ;
  478.     XCHG
  479.     POP    H
  480.     DAD    D
  481.     SHLD    LAST        ; save
  482.      RET            ;
  483. INRADDR:
  484.     PUSH    B
  485.     PUSH    D
  486.     PUSH    H
  487.     LHLD    DMAADDR        ; add 128 to DMA addr
  488.     LXI    D,128
  489.     DAD    D
  490.     SHLD    DMAADDR
  491.     XCHG
  492.     CALL    SETADDR
  493. ;
  494.     LHLD    DMAADDR
  495.     LDA    MEMSIZ
  496.     DCR    A
  497.     SUB    H
  498.     JNC    SIZOK
  499.     LXI    D,SIZMSG
  500.     CALL    PERR 
  501.     STC
  502. SIZOK:
  503.     POP    H
  504.     POP    D
  505.     POP    B
  506.     RET
  507. SETADDR:
  508.     CALL    SAVALL
  509.     MVI    C,SETDMA    ; set DMA addr to DE
  510.     CALL    BDOS        ;
  511.     JMP    RSTALL
  512. PERR:
  513.     PUSH    D
  514.     LXI    D,ERRMSG
  515.     CALL    PSTR
  516.     POP    D
  517.     CALL    PSTR
  518.     RET
  519. ;
  520. ;    data storage
  521. ;
  522. TEMPBUF    DS    50
  523. TEMP    DB    0
  524. FLAG    DB    0
  525. TYPE    DB    0
  526. TOTAL    DB    0
  527. FIRST    DW    0
  528. LAST    DB    0FFH,0
  529. DMAADDR    DW    BUFFER
  530. MODMSG    DB    'illegal mode',CR,LF,EOL    
  531. SYNMSG    DB    'illegal syntax'
  532.     DB    CR,LF,EOL
  533. OPENERR DB    'file cannot be found',CR,LF,EOL
  534. FMSG    DB    '  data found at address: ',EOL
  535. FFMSG1    DB    '  data found in sector: '
  536. FFMSG2    DS    3
  537.           DB    ' byte: '
  538. FFMSG3    DS    3
  539.     DB    CR,LF,EOL
  540. NFMSG    DB    '  data cannot be found',CR,LF,EOL
  541. SIZMSG    DB    'file too large',CR,LF,CR,LF,EOL
  542. ERRMSG    DB    BELL,'  error: ',EOL
  543. APNTR    DW    TBUFF+5        ; ASCII pntr
  544. BPNTR    DW    TBUFF+5        ; binary pntr
  545. FNPNTR    DW    0        ; filename pntr
  546. FILEFCB    DB    0,'           ',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  547. BUFFER    EQU    $
  548. ;
  549.     END    START
  550.